/*
 * @Author: Xujianchen
 * @Date: 2025-10-17 14:33:17
 * @LastEditTime: 2025-10-23 09:00:06
 * @LastEditors: Xujianchen
 * @Description: 类型判断函数
 */
type TypeMap = {
  String: string
  Number: number
  Boolean: boolean
  Array: unknown[]
  Object: Record<string, unknown>
  Function: (...args: any[]) => any
  AsyncFunction: (...args: any[]) => Promise<any>
  Undefined: undefined
  Null: null
  Date: Date
}

const checkTypeFn = <T extends keyof TypeMap>(type: T) => {
  return (value: unknown): value is TypeMap[T] =>
    Object.prototype.toString.call(value) === `[object ${type}]`
}

export const isFunc = checkTypeFn('Function')
export const isAsyncFunc = checkTypeFn('AsyncFunction')
export const isUndefined = checkTypeFn('Undefined')
export const isArray = checkTypeFn('Array')
export const isString = checkTypeFn('String')
export const isObject = checkTypeFn('Object')
export const isNumber = checkTypeFn('Number')
export const isDate = checkTypeFn('Date')
export const isBoolean = checkTypeFn('Boolean')
export const isHtmlElement = (node: Node) => node && node.nodeType === Node.ELEMENT_NODE
export const isDefined = <T>(val: T): boolean => val !== undefined && val !== null

// 布尔类型转换
export const toBoolean = (value: string, truthyValues = ['true']): boolean => {
  const normalizedValue = String(value).toLowerCase().trim()
  return truthyValues.includes(normalizedValue)
}

// 是否是数字字符串
export const isStringNumber = (value: string): boolean => {
  if (!isString(value)) {
    return false
  }
  return !Number.isNaN(Number(value))
}
